package cn.yangliu.nacos.management.web.sys;

import java.util.Objects;

import cn.yangliu.jpa.handler.JpaHandler;
import cn.yangliu.nacos.comm.config.security.annotations.Authorize;
import cn.yangliu.nacos.comm.enums.GlobalResultCode;
import cn.yangliu.nacos.comm.ex.GlobalException;
import cn.yangliu.nacos.comm.model.Oauth2Token;
import cn.yangliu.nacos.comm.model.Oauth2UpdateOtherPasswordModel;
import cn.yangliu.nacos.comm.model.Oauth2UserModel;
import cn.yangliu.nacos.comm.oauth.TokenHandler;
import cn.yangliu.nacos.comm.tools.SecurityUtils;
import cn.yangliu.nacos.management.entity.sys.User;
import cn.yangliu.nacos.management.model.UserQueryModel;
import cn.yangliu.nacos.management.model.UserUpdateModel;
import cn.yangliu.nacos.management.service.sys.UserService;
import cn.yangliu.operation.annotation.Action;
import cn.yangliu.operation.annotation.Module;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * The type of nacos.
 *
 * @author 问道于盲
 * @date 2020 -01-01
 */
@RestController
@Api(value = "系统用户管理", tags = "系统用户管理")
@RequestMapping("/sys/user")
@Module("系统管理-用户管理")
public class UserController {

    /**
     * current class instance's member.
     * The Token handler.
     */
    @Autowired
    private TokenHandler tokenHandler;

    /**
     * current class instance's member.
     * The User service.
     */
    @Autowired
    private UserService userService;

    /**
     * current class instance's member.
     * The Jpa handler.
     */
    private JpaHandler jpaHandler = JpaHandler.INSTANCE;

    /**
     * Find by id user.
     *
     * @param id the id
     * @return the user
     */
    @GetMapping("/{id}")
    @ApiOperation("根据id查询用户")
    @Authorize("user:query")
    public User findById(@PathVariable("id") Long id) {
        return userService.findById(id).orElse(null);
    }

    /**
     * Page page.
     *
     * @param model the model
     * @return the page
     */
    @GetMapping("/page")
    @ApiOperation("分页查询用户")
    @Authorize("user:query")
    public Page<User> page(@Validated UserQueryModel model) {
        Specification<User> specification = jpaHandler.buildSpecification(model);
        return userService.findAll(specification, model.build());
    }

    /**
     * Update roles user.
     *
     * @param model the model
     * @return the user
     */
    @PutMapping
    @ApiOperation("修改用户角色")
    @Authorize("user:update")
    @Action("修改用户角色")
    public User updateRoles(@RequestBody @Validated UserUpdateModel model) {
        return userService.updateRoles(model);
    }

    /**
     * Password boolean.
     *
     * @param model the model
     * @return the boolean
     */
    @PutMapping("/password")
    @ApiOperation("重置密码")
    @Authorize("user:reset")
    @Action("重置密码")
    public boolean password(@RequestBody @Validated Oauth2UpdateOtherPasswordModel model) {
        Oauth2UserModel currentUser = SecurityUtils.getCurrentUser();
        String username = currentUser.getUsername();
        Oauth2Token oauth2Token = tokenHandler.load(username);
        return userService.updateOtherPassword(model, oauth2Token.getAccessToken());
    }

    /**
     * Update.
     *
     * @param id the id
     */
    @DeleteMapping("/{id}")
    @ApiOperation("删除用户")
    @Authorize("user:delete")
    @Action("删除用户")
    public void update(@PathVariable("id") Long id) {
        Oauth2UserModel currentUser = SecurityUtils.getCurrentUser();
        if (Objects.equals(id, currentUser.getId())) {
            throw new GlobalException(GlobalResultCode.OPERATE_SELF_FORBIDEN);
        }
        userService.deleteById(id);
    }
}
